package edu.lingnan.librarymanage.service.impl;

import edu.lingnan.librarymanage.core.bean.*;
import edu.lingnan.librarymanage.core.constant.LibraryManageConstant;
import edu.lingnan.librarymanage.core.exception.BookException;
import edu.lingnan.librarymanage.core.vo.BookBaseInfo;
import edu.lingnan.librarymanage.core.vo.BookItemVO;
import edu.lingnan.librarymanage.core.vo.BookVO;
import edu.lingnan.librarymanage.core.vo.PageDataVO;
import edu.lingnan.librarymanage.repository.*;
import edu.lingnan.librarymanage.service.BookService;
import edu.lingnan.librarymanage.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author cql
 */
@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookRepository bookRepository;

    @Autowired
    private CategoryRepository categoryRepository;

    @Autowired
    private AuthorRepository authorRepository;

    @Autowired
    private BorrowRepository borrowRepository;

    @Autowired
    private BookItemRepository bookItemRepository;

    @Override
    public PageDataVO<BookBaseInfo> findBookByCategory(Integer categoryId, Integer pageSize, Integer current, String name) {

        Specification sp = new Specification<Book>() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
                Predicate predicate = null;
                if (!categoryId.equals(0)) {
                    predicate = criteriaBuilder.and(criteriaBuilder.equal(root.get("categoryId"), categoryId),
                            criteriaBuilder.like(root.get("name").as(String.class), "%" + name + "%"));

                } else if (categoryId.equals(0)) {
                    predicate = criteriaBuilder.like(root.get("name").as(String.class), "%" + name + "%");

                }
                return predicate;
            }
        };

        PageRequest pageRequest = PageRequest.of(current - 1, pageSize);
        Page<Book> page = bookRepository.findAll(sp, pageRequest);
        PageDataVO<BookBaseInfo> pageDataVO = new PageDataVO();

        page.getContent().forEach(System.out::println);


        List<BookBaseInfo> bookVOS = page.getContent().stream().map(book -> {
            BookBaseInfo b = new BookBaseInfo();
            BeanUtils.copyProperties(book, b);

            /**
             * 1.分类信息
             * 2.作者信息
             */
            Category category = categoryRepository.findById(book.getCategoryId()).get();
            if (category != null) {
                b.setCategory(category.getName());
            }
            Optional<Author> optionalAuthor = authorRepository.findById(book.getAuthorId());
            if (optionalAuthor.isPresent()) {
                b.setAuthor(optionalAuthor.get().getName());
            }
            return b;
        }).collect(Collectors.toList());


        pageDataVO.setContent(bookVOS);
        pageDataVO.setTotalPage(page.getTotalPages());
        pageDataVO.setTotalElement((int) page.getTotalElements());

        return pageDataVO;
    }

    @Override
    public BookVO findBookDetail(Integer bookId) {
        BookVO bookVO = new BookVO();
        if (bookId == null) {
            throw new BookException("图书不存在");
        }

        Optional<Book> optionalBook = bookRepository.findById(bookId);
        if (optionalBook == null && optionalBook.get() == null) {
            throw new BookException("图书不存在");
        }

        Book book = optionalBook.get();
        BeanUtils.copyProperties(book, bookVO);
        /**
         * 获取分类信息,获取作者信息,获取位置信息
         */
        Category category = categoryRepository.findById(book.getCategoryId()).get();
        bookVO.setCategory(category.getName());

        Author author = authorRepository.findById(book.getAuthorId()).get();
        bookVO.setAuthor(author.getName());
        bookVO.setAuthorDesc(author.getDescription());

        /**
         * 位置信息
         */
        List<BookItemVO> bookItems = bookItemRepository.findByBookId(book.getBookId()).stream().map(item -> {
            BookItemVO bookItemVO = new BookItemVO();

            BeanUtils.copyProperties(item, bookItemVO);

            bookItemVO.setBorrow(item.getIsBorrow().equals(LibraryManageConstant.IS_NOT_BORROW) ? false : true);

            return bookItemVO;
        }).collect(Collectors.toList());


        bookVO.setItems(bookItems);

        return bookVO;
    }
}
